home *** CD-ROM | disk | FTP | other *** search
/ By Popular Request 2.0 / By Popular Request 2.0 (Arsenal Computer).ISO / amiga_6 / tiffdtyp.lha / sources / dispatch.c < prev    next >
C/C++ Source or Header  |  1995-07-08  |  26KB  |  876 lines

  1. /* 
  2.  *     dispatch.c
  3.  */
  4.  
  5. #include "classbase.h"
  6. #include "TIFF.h"
  7. #include "TIFFTags.h"
  8. #include <libraries/xpksub.h>
  9.  
  10. #define    DB(x)    x;
  11. #define    DC(x)    ;
  12. #define    DP(x)    ;
  13.  
  14. #define    SWAPW(a)    (Rev ? (WORD)(((UWORD)a>>8)+((((UWORD)a&0xff)<<8))) : a)
  15. #define    SWAPU(a)    (Rev ? (UWORD)(((UWORD)a>>8)+((((UWORD)a&0xff)<<8))) : a)
  16. #define    SWAPL(a)    (Rev ? (LONG)(((ULONG)a>>24)+(((ULONG)a&0xff0000)>>8)+(((ULONG)a&0xff00)<<8)+(((ULONG)a&0xff)<<24)): a)
  17.  
  18. void ASM ReadShorts(REG (a0) BPTR fh, REG (a1) USHORT *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
  19. void ASM ReadLongs(REG (a0) BPTR fh, REG (a1) ULONG *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
  20. void ASM ReadRational(REG (a0) BPTR fh, REG (a1) struct Rational *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
  21. void ASM ReadBytes(REG (a0) BPTR fh, REG (a1) UBYTE *buffer, REG (a2) TIFFTagItem *tag,REG (a6) struct ClassBase *cb);
  22. int  ASM UnPackLZW(REG (a0) UBYTE *source, REG (a1) UBYTE *dest, REG (d0) int len, REG (a6) struct ClassBase *cb);
  23. void ASM InitializeStringTable(REG (a6) struct ClassBase *cb);
  24. void ASM GetNextCode(REG (a6) struct ClassBase *cb);
  25. void ASM AddStringToTable(REG (d0) int code,REG (d1) int newchar,REG (a6) struct ClassBase *cb);
  26. void ASM WriteString(REG (d0) int code,REG (a6) struct ClassBase *cb);
  27. void ASM IsInTable(REG (d0) int code,REG (a6) struct ClassBase *cb);
  28. void ASM Chunky2Planar(REG (d0) int width,REG (a0) UBYTE *buffer,REG (a1) UBYTE *tempbmp);
  29.  
  30. #define TAGVAL(a,b)    (SWAPW(a.Type)==TT_BYTE ? a.CValue[b] :            \
  31.                     (SWAPW(a.Type)==TT_SHORT ? SWAPW(a.SValue[b]) :    \
  32.                     (SWAPW(a.Type)==TT_LONG ? SWAPL(a.LValue) :    \
  33.                     ~0)))
  34.  
  35. char                 Rev=0;    /* flag for reverse byte order */
  36.  
  37. void                 *pool,*poolchip;    /* memory pool for allocations */
  38.  
  39. struct BitMapHeader *bmhd;
  40.  
  41. struct StringEntry 
  42.         {
  43.             struct StringEntry *OldCode;
  44.             UWORD  StringLen;
  45.             UBYTE  FirstChar;
  46.             UBYTE  LastChar;
  47.         } *StringTable;
  48.  
  49. TIFFBasicFields BF={
  50.             2,                /* GrayResponseUnit */
  51.             0,                /* NewSubfileType */
  52.             0,                /* PhotometricInterpretation */
  53.             CHUNKY,            /* PlanarConfiguration */
  54.             NO_PREDICTOR,    /* Predictor */
  55.             INCH,            /* ResolutionUnit */
  56.             1,                /* SamplesPerPixel */
  57.             NO_COMPRESSION,    /* Compression */
  58.             {1},            /* BitsPerSample */
  59.             NULL,            /* ColorMap      */
  60.             NULL,            /* ColorResponseCurve */
  61.             NULL,            /* GrayResponseCurve */
  62.             0,                /* ImageLength */
  63.             0,                /* ImageWidth */
  64.             (USHORT)~0,        /* RowsPerStrip */
  65.             NULL,            /* StripByteCounts */
  66.             NULL,            /* StripOffsets */
  67.             };
  68.  
  69. TIFFInformationFields IF={NULL,NULL,NULL,NULL,NULL,NULL,};
  70.  
  71. TIFFFaxFields FF={0,0};
  72.  
  73. TIFFDocumentFields DF={
  74.         NULL,                /* DocumentName */
  75.         NULL,                /* PageName */
  76.         LINE_ART,            /* Threshhold */
  77.         TOPLEFT,            /* Orientation */
  78.         0,                    /* CellLength */
  79.         0,                    /* CellWidth */
  80.         MSB_FIRST,            /* FillOrder */
  81.         0,0,                /* PageNumber */
  82.         {0xffff,0xffff,0xffff,0xffff,
  83.          0xffff,0xffff,0xffff,0xffff},    /* MaxSampleValue */
  84.         {0,0,0,0,0,0,0,0},    /* MinSampleValue */
  85.         };
  86.  
  87. /*****************************************************************************/
  88.  
  89. struct RGBQuad
  90. {
  91.     UBYTE rgbBlue;
  92.     UBYTE rgbGreen;
  93.     UBYTE rgbRed;
  94.     UBYTE rgbReserved;
  95. };
  96.  
  97. #define    QSIZE    (sizeof (struct RGBQuad))
  98.  
  99. /*****************************************************************************/
  100.  
  101. BOOL ASM GetTIFF (REG (a6) struct ClassBase *cb, REG (a0) Class * cl, REG (a2) Object * o, REG (a1) struct TagItem * attrs);
  102. BOOL ASM convert(REG (a6) struct ClassBase *cb,REG (a0) BPTR fh, REG (a1) Object * o);
  103.  
  104. ULONG setdtattrs (struct ClassBase *cb, Object * o, ULONG data,...)
  105. {
  106.     return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
  107. }
  108.  
  109. /*****************************************************************************/
  110.  
  111. ULONG getdtattrs (struct ClassBase *cb, Object * o, ULONG data,...)
  112. {
  113.     return (GetDTAttrsA (o, (struct TagItem *) & data));
  114. }
  115.  
  116. /*****************************************************************************/
  117.  
  118. Class *initClass (struct ClassBase *cb)
  119. {
  120.     Class *cl;
  121.  
  122.     if (cl = MakeClass (TIFFDTCLASS, PICTUREDTCLASS, NULL, NULL, 0L))
  123.     {
  124.     cl->cl_Dispatcher.h_Entry = Dispatch;
  125.     cl->cl_UserData           = (ULONG) cb;
  126.     AddClass (cl);
  127.     }
  128.  
  129.     return (cl);
  130. }
  131.  
  132. /*****************************************************************************/
  133.  
  134. ULONG ASM Dispatch (REG (a0) Class * cl, REG (a2) Object * o, REG (a1) Msg msg)
  135. {
  136.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  137.     ULONG retval;
  138.  
  139.     switch (msg->MethodID)
  140.     {
  141.     case OM_NEW:
  142.         if (retval = DoSuperMethodA (cl, o, msg))
  143.         {
  144.         DB (KPrintF ("OM_NEW\n"));
  145.  
  146.         if (!GetTIFF (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList))
  147.         {
  148.             CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
  149.             return NULL;
  150.         }
  151.         }
  152.         break;
  153.  
  154.         /* Let the superclass handle everything else */
  155.     default:
  156.         retval = (ULONG) DoSuperMethodA (cl, o, msg);
  157.         break;
  158.     }
  159.  
  160.     return (retval);
  161. }
  162.  
  163. BOOL ASM GetTIFF (REG (a6) struct ClassBase *cb, REG (a0) Class * cl, REG (a2) Object * o, REG (a1) struct TagItem * attrs)
  164. {
  165.     TIFFImageFileHeader ifh;
  166.     TIFFTagItem tti;
  167.     short  NumTags;
  168.     LONG i;
  169.     STRPTR title;
  170.     BPTR fh;
  171.     BOOL flag=FALSE;
  172.  
  173.     title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
  174.     setdtattrs (cb, o,DTA_ObjName,title,TAG_DONE);
  175.  
  176.     DB (KPrintF ("GetTIFF %s\n",title));
  177.  
  178.     pool=CreatePool(MEMF_CLEAR,8192,8192);
  179.     if(!pool) return FALSE;
  180.  
  181.     if ((getdtattrs (cb, o, DTA_Handle, &fh, PDTA_BitMapHeader, &bmhd, TAG_DONE) == 2) && fh)
  182.     {
  183.  
  184.         DB (KPrintF ("GetDTAttrs\n"));
  185.  
  186.         Seek (fh, 0L, OFFSET_BEGINNING);
  187.  
  188.         /* read  image file header */
  189.  
  190.         if (Read (fh, &ifh, TIFHSIZE) == TIFHSIZE)
  191.         {
  192.             if (ifh.ByteOrder == 'II')
  193.                 {
  194.                 DB (KPrintF ("reverse byte order\n"));
  195.                 Rev=1;
  196.                 }
  197.             else if (ifh.ByteOrder == 'MM')
  198.                 {
  199.                 DB (KPrintF ("normal byte order\n"));
  200.                 Rev=0;
  201.                 }
  202.             else
  203.                 SetIoErr (ERROR_OBJECT_WRONG_TYPE);
  204.  
  205.             DB (KPrintF ("Version %lx %lx\n",(long)ifh.Version,(long)SWAPW(ifh.Version)));
  206.             DB (KPrintF ("Offset %lx %lx\n",ifh.Offset,SWAPL(ifh.Offset)));
  207.             
  208.         }
  209.         else 
  210.         {
  211.             DB (KPrintF ("couldn't read information\n"));
  212.             DeletePool(pool);
  213.             return FALSE;
  214.         }
  215.  
  216.         Seek (fh, SWAPL(ifh.Offset), OFFSET_BEGINNING);
  217.  
  218.         /* read image file directory */
  219.  
  220.         if (Read (fh, &NumTags, sizeof(short)) == sizeof(short))
  221.         {
  222.             NumTags=SWAPW(NumTags);
  223.             for(i=0;i<NumTags;i++)
  224.             {
  225.                 if (Read (fh, &tti, TTISIZE) == TTISIZE)
  226.                 {
  227.  
  228.                     DB ( KPrintF("%ld:\n",(long)SWAPW(tti.Tag)));
  229.                     tti.Count=SWAPL (tti.Count);
  230.                     switch (SWAPW (tti.Tag))
  231.                     {
  232.                         case TT_NewSubfileType:
  233.                             BF.NewSubfileType=TAGVAL(tti,0);
  234.                             DB ( KPrintF("tag NewSubfileType\n"));
  235.                             break;
  236.                         case TT_SubfileType:
  237.                             switch(TAGVAL(tti,0))
  238.                             {
  239.                                 case REDUCED_RESOLUTION:
  240.                                     BF.NewSubfileType|=REDUCED;
  241.                                     break;
  242.                                 case MULTI_PAGE:
  243.                                     BF.NewSubfileType|=MULTIPAGE;
  244.                                     break;
  245.                             }
  246.                             DB ( KPrintF("tag SubfileType\n"));
  247.                             break;
  248.                         case TT_ImageWidth:
  249.                             bmhd->bmh_Width=BF.ImageWidth=TAGVAL(tti,0);
  250.                             DB ( KPrintF("ImageWidth %ld\n",BF.ImageWidth));
  251.                             break;
  252.                         case TT_ImageLength:
  253.                             bmhd->bmh_Height=BF.ImageLength=TAGVAL(tti,0);
  254.                             DB ( KPrintF("ImageLength %ld\n",BF.ImageLength));
  255.                             if(BF.RowsPerStrip==(USHORT)~0)
  256.                                 BF.RowsPerStrip=BF.ImageLength;
  257.                             break;
  258.                         case TT_BitsPerSample:
  259.                             if(tti.Count>2)
  260.                                 ReadShorts(fh,BF.BitsPerSample,&tti,cb);
  261.                             else
  262.                                 BF.BitsPerSample[0]=TAGVAL(tti,0);
  263.                             if(tti.Count==2)
  264.                                 BF.BitsPerSample[1]=TAGVAL(tti,1);
  265.                             if(DF.MaxSampleValue[0]==~0)
  266.                             {
  267.                                 int i;
  268.                                 for(i=0;i<8;i++)
  269.                                     DF.MaxSampleValue[i]=(2<<BF.BitsPerSample[i])-1;
  270.                             }
  271.                             DB ( KPrintF("BitPerSample %ld %lx\n",(long)BF.BitsPerSample[0],(long)tti.LValue));
  272.                             break;
  273.                         case TT_Compression:    
  274.                             BF.Compression=TAGVAL(tti,0);
  275.                             DB ( KPrintF("Compression %ld\n",(long)BF.Compression));
  276.                             break;
  277.                         case TT_PhotometricInterpretation:
  278.                             BF.PhotometricInterpretation=TAGVAL(tti,0);
  279.                             DB ( KPrintF("PhotometricInterpretation %ld\n",(long)BF.PhotometricInterpretation));
  280.                             break;
  281.                         case TT_Threshholding:
  282.                             DF.Threshholding=TAGVAL(tti,0);
  283.                             DB ( KPrintF("Threshholding %ld\n",(long)DF.Threshholding));
  284.                             break;
  285.                         case TT_CellWidth:
  286.                             DF.CellWidth=TAGVAL(tti,0);
  287.                             DB ( KPrintF("CellWidth %ld\n",(long)DF.CellWidth));
  288.                             break;
  289.                         case TT_CellLength:
  290.                             DF.CellLength=TAGVAL(tti,0);
  291.                             DB ( KPrintF("CellLength %ld\n",(long)DF.CellLength));
  292.                             break;
  293.                         case TT_FillOrder:
  294.                             DF.FillOrder=TAGVAL(tti,0);
  295.                             DB ( KPrintF("FillOrder %ld\n",(long)DF.FillOrder));
  296.                             break;
  297.                         case TT_DocumentName:
  298.                             DF.DocumentName=AllocPooled(pool,tti.Count);
  299.                             if(!DF.DocumentName) goto abort;
  300.                             ReadBytes(fh,DF.DocumentName,&tti,cb);
  301.                             DB ( KPrintF("DocumentName %s\n",DF.DocumentName));
  302.                             break;
  303.                         case TT_ImageDescription:
  304.                             IF.ImageDescription=AllocPooled(pool,tti.Count);
  305.                             if(!IF.ImageDescription) goto abort;
  306.                             ReadBytes(fh,IF.ImageDescription,&tti,cb);
  307.                             DB ( KPrintF("ImageDescription %s\n",IF.ImageDescription));
  308.                             break;
  309.                         case TT_Make:
  310.                             IF.Make=AllocPooled(pool,tti.Count);
  311.                             if(!IF.Make) goto abort;
  312.                             ReadBytes(fh,IF.Make,&tti,cb);
  313.                             DB ( KPrintF("Make %s\n",IF.Make));
  314.                             break;
  315.                         case TT_Model:
  316.                             IF.Model=AllocPooled(pool,tti.Count);
  317.                             if(!IF.Model) goto abort;
  318.                             ReadBytes(fh,IF.Model,&tti,cb);
  319.                             DB ( KPrintF("Model %s\n",IF.Model));
  320.                             break;
  321.                         case TT_StripOffsets:
  322.                             BF.StripOffsets=AllocPooled(pool,tti.Count*sizeof(long));
  323.                             DB ( KPrintF("StripOffsets %ld\n",(long)tti.Count));
  324.                             if(!BF.StripOffsets) goto abort;
  325.                             ReadLongs(fh,BF.StripOffsets,&tti,cb);
  326.                             break;
  327.                         case TT_Orientation:
  328.                             DF.Orientation=TAGVAL(tti,0);
  329.                             DB ( KPrintF("Orientation %ld\n",(long)DF.Orientation));
  330.                             break;
  331.                         case TT_SamplesPerPixel:
  332.                             BF.SamplesPerPixel=TAGVAL(tti,0);
  333.                             DB ( KPrintF("SamplePerPixel %ld\n",(long)BF.SamplesPerPixel));
  334.                             break;
  335.                         case TT_RowsPerStrip:
  336.                             BF.RowsPerStrip=TAGVAL(tti,0);
  337.                             DB ( KPrintF("RowsPerStrip %ld\n",(long)BF.RowsPerStrip));
  338.                             break;
  339.                         case TT_StripByteCounts:                
  340.                             BF.StripByteCounts=AllocPooled(pool,tti.Count*sizeof(long));
  341.                             DB ( KPrintF("StripByteCounts %ld\n",(long)tti.Count));
  342.                             if(!BF.StripByteCounts) goto abort;
  343.                             ReadLongs(fh,BF.StripByteCounts,&tti,cb);
  344.                             break;
  345.                         case TT_MaxSampleValue:
  346.                             DB ( KPrintF("MaxSampleValue %ld\n",(long)tti.Count));
  347.                             ReadShorts(fh,DF.MaxSampleValue,&tti,cb);
  348.                             break;
  349.                         case TT_MinSampleValue:
  350.                             DB ( KPrintF("MinSampleValue %ld\n",(long)tti.Count));
  351.                             ReadShorts(fh,DF.MinSampleValue,&tti,cb);
  352.                             break;
  353.                         case TT_XResolution:
  354.                             ReadRational(fh,&BF.XResolution,&tti,cb);
  355.                             DB ( KPrintF("XResolution %ld / %ld\n",(long)BF.XResolution.Numerator,BF.XResolution.Denominator));
  356.                             break;
  357.                         case TT_YResolution:
  358.                             ReadRational(fh,&BF.YResolution,&tti,cb);
  359.                             DB ( KPrintF("YResolution %ld / %ld\n",(long)BF.YResolution.Numerator,BF.YResolution.Denominator));
  360.                             break;
  361.                         case TT_PlanarConfiguration:
  362.                             BF.PlanarConfiguration=TAGVAL(tti,0);
  363.                             DB ( KPrintF("PlanarConfiguration %ld\n",(long)BF.PlanarConfiguration));
  364.                         break;
  365.                         case TT_PageName:
  366.                             DF.PageName=AllocPooled(pool,tti.Count);
  367.                             if(!DF.PageName) goto abort;
  368.                             ReadBytes(fh,DF.PageName,&tti,cb);
  369.                             DB ( KPrintF("PageName %s\n",DF.PageName));
  370.                             break;
  371.                         case TT_XPosition:
  372.                             ReadRational(fh,&DF.XPosition,&tti,cb);
  373.                             DB ( KPrintF("XPosition %ld / %ld\n",(long)DF.XPosition.Numerator,DF.XPosition.Denominator));
  374.                             break;
  375.                         case TT_YPosition:
  376.                             ReadRational(fh,&DF.XPosition,&tti,cb);
  377.                             DB ( KPrintF("YPosition %ld / %ld\n",(long)DF.YPosition.Numerator,DF.YPosition.Denominator));
  378.                             break;
  379.                         case TT_GrayResponseUnit:
  380.                             BF.GrayResponseUnit=TAGVAL(tti,0);
  381.                             DB ( KPrintF("GrayResponseUnit %d\n",(int)BF.GrayResponseUnit));
  382.                             break;
  383.                         case TT_GrayResponseCurve:
  384.                             BF.GrayResponseCurve=AllocPooled(pool,tti.Count*sizeof(short));
  385.                             DB ( KPrintF("GrayResponseCurve size %ld\n",(long)tti.Count));
  386.                             if(!BF.GrayResponseCurve) goto abort;
  387.                             ReadShorts(fh,BF.GrayResponseCurve,&tti,cb);
  388.                             break;
  389.                         case TT_Group3Options:
  390.                             FF.Group3Options=TAGVAL(tti,0);
  391.                             DB ( KPrintF("Group3Options %x\n",(int)FF.Group3Options));
  392.                             break;
  393.                         case TT_Group4Options:                    
  394.                             FF.Group4Options=TAGVAL(tti,0);
  395.                             DB ( KPrintF("Group4Options %x\n",(int)FF.Group4Options));
  396.                             break;
  397.                         case TT_ResolutionUnit:
  398.                             BF.ResolutionUnit=TAGVAL(tti,0);
  399.                             DB ( KPrintF("ResolutionUnit %ld\n",(long)BF.ResolutionUnit));
  400.                             break;
  401.                         case TT_PageNumber:
  402.                             DB ( KPrintF("PageNumber\n"));
  403.                             ReadShorts(fh,DF.PageNumber,&tti,cb);
  404.                             DB ( KPrintF(" %d %d\n",(int)DF.PageNumber[0],(int)DF.PageNumber[1]));
  405.                         break;
  406.                         case TT_ColorResponseCurves:
  407.                             BF.ColorResponseCurves=AllocPooled(pool,tti.Count*sizeof(short));
  408.                             DB ( KPrintF("ColorResponseCurves size %ld\n",(long)tti.Count));
  409.                             if(!BF.ColorResponseCurves) goto abort;
  410.                             ReadShorts(fh,BF.ColorResponseCurves,&tti,cb);
  411.                             break;
  412.                         case TT_Software:
  413.                             IF.Software=AllocPooled(pool,tti.Count);
  414.                             DB ( KPrintF("Software %s\n",IF.Software));
  415.                             if(!IF.Software) goto abort;
  416.                             ReadBytes(fh,IF.Software,&tti,cb);
  417.                             break;
  418.                         case TT_DateTime:
  419.                             DB ( KPrintF("DateTime %s\n",IF.DateTime));
  420.                             ReadBytes(fh,IF.DateTime,&tti,cb);
  421.                             break;
  422.                         case TT_Artist:
  423.                             IF.Artist=AllocPooled(pool,tti.Count);
  424.                             DB ( KPrintF("Artist %s\n",IF.Artist));
  425.                             if(!IF.Artist) goto abort;
  426.                             ReadBytes(fh,IF.Artist,&tti,cb);
  427.                             break;
  428.                         case TT_HostComputer:
  429.                             IF.HostComputer=AllocPooled(pool,tti.Count);
  430.                             DB ( KPrintF("HostComputer %s\n",IF.HostComputer));
  431.                             if(!IF.HostComputer) goto abort;
  432.                             ReadBytes(fh,IF.HostComputer,&tti,cb);
  433.                             break;
  434.                         case TT_Predictor:
  435.                             BF.Predictor=TAGVAL(tti,0);
  436.                             DB ( KPrintF("Predictor %ld\n",(long)BF.Predictor));
  437.                             break;
  438.                         case TT_WhitePoint:
  439.                             DB ( KPrintF("tag WhitePoint\n"));
  440.                             break;
  441.                         case TT_PrimaryChromaticities:
  442.                             DB ( KPrintF("tag PrimaryChromaticities\n"));
  443.                             break;
  444.                         case TT_ColorMap:
  445.                             BF.ColorMap=AllocPooled(pool,tti.Count*sizeof(short));
  446.                             DB ( KPrintF("ColorMap size %ld\n",(long)tti.Count));
  447.                             if(!BF.ColorMap) goto abort;
  448.                             ReadShorts(fh,BF.ColorMap,&tti,cb);
  449.                         break;
  450.                         case TT_InkSet:
  451.                             DB ( KPrintF("tag InkSet\n"));
  452.                         break;
  453.                         case TT_InkNames:
  454.                             DB ( KPrintF("tag InkNames\n"));
  455.                         break;
  456.                         case TT_TargetPrinter:
  457.                             DB ( KPrintF("tag TargetPrinter\n"));
  458.                         break;
  459.  
  460.                         case TT_JPEGProc:
  461.                             DB ( KPrintF("tag JPEGProc\n"));
  462.                         break;
  463.                         case TT_JPEGInterchangeFormat: 
  464.                             DB ( KPrintF("tag JPEGInterchangeFormat:\n"));
  465.                         break;
  466.                         case TT_JPEGInterchangeFormatLength:
  467.                             DB ( KPrintF("tag JPEGInterchangeFormatLength\n"));
  468.                         break;
  469.                         case TT_JPEGLosslessPredictors:
  470.                             DB ( KPrintF("tag JPEGLosslessPredictors\n"));
  471.                         break;
  472.                         case TT_JPEGQTables:
  473.                             DB ( KPrintF("tag JPEGQTables\n"));
  474.                         break;
  475.                         case TT_JPEGDCTables:
  476.                             DB ( KPrintF("tag JPEGDCTables\n"));
  477.                         break;
  478.                         case TT_JPEGACTables:
  479.                             DB ( KPrintF("tag JPEGACTables\n"));
  480.                         break;
  481.  
  482.                         case TT_YCbCrCoefficents:
  483.                             DB ( KPrintF("tag YCbCrCoefficents\n"));
  484.                         break;
  485.                         case TT_YCbCrSubSampling:
  486.                             DB ( KPrintF("tag YCbCrSubSampling\n"));
  487.                         break;
  488.                         case TT_YCbCrPositioning:
  489.                             DB ( KPrintF("tag YCbCrPositioning\n"));
  490.                         break;
  491.                         default:
  492.                             DB (KPrintF ("Unknown tag %ld\n", (long)SWAPW (tti.Tag)));
  493.                         break;
  494.                     }
  495.                 }
  496.                 else 
  497.                 {
  498.                     DB (KPrintF ("couldn't read information\n"));
  499.                     DeletePool(pool);
  500.                     return FALSE;
  501.                 }
  502.             }
  503.         }
  504.     }
  505.     
  506.      flag=convert(cb,fh,o);
  507.  
  508. abort:
  509.     DeletePool(pool);
  510.     return flag;
  511. }
  512.  
  513. /*    converts the image in BitMap format */
  514.  
  515. BOOL ASM convert(REG (a6) struct ClassBase *cb,REG (a0) BPTR fh, REG (a1) Object * o) 
  516.  
  517. {
  518.     ULONG modeid = HIRES_KEY;
  519.     struct RastPort rp;
  520.     LONG i, j, k, l, m;
  521.     struct BitMap *bm=NULL,tbm;
  522.     UBYTE *buffer,*buffer3,*ErrRed,*ErrGreen,*ErrBlue;
  523.     LONG depth,ncolors;
  524.     struct ColorRegister *cmap;
  525.     LONG *cregs;
  526.  
  527.     DB (KPrintF ("Convert:\n"));
  528.  
  529.     DB ( KPrintF("BitPerSample %ld \n",(long)BF.BitsPerSample[0]));
  530.     depth=BF.BitsPerSample[0];
  531.  
  532.     DB ( KPrintF("depth %ld \n",(long)depth));
  533.     ncolors=1<<depth;
  534.  
  535.     DB (KPrintF ("NColors %ld\n",ncolors));
  536.  
  537.     setdtattrs (cb, o, PDTA_NumColors, ncolors, TAG_DONE);
  538.  
  539.     getdtattrs (cb, o,
  540.         PDTA_ColorRegisters,    (ULONG)&cmap,
  541.         PDTA_CRegs,        &cregs,
  542.         TAG_DONE);
  543.  
  544.     switch(BF.Compression)
  545.     {
  546.         case NO_COMPRESSION:
  547.             break;
  548.         case LZW:
  549.             
  550.                 /* allocate LZW table */
  551.  
  552.             StringTable=AllocPooled(pool,sizeof(struct StringEntry)*4096);
  553.             if(StringTable==NULL)
  554.             {
  555.                 DB (KPrintF ("Unable to allocate LZW string table\n"));
  556.                 goto abort;
  557.             }
  558.  
  559.                 /* initialize first entries for lzw decompression table */
  560.  
  561.             for(i=0;i<256;i++)
  562.             {
  563.                 StringTable[i].StringLen=1;
  564.                 StringTable[i].FirstChar=StringTable[i].LastChar=i;
  565.             }
  566.             break;
  567.         default:
  568.             DB (KPrintF ("Unsupported Compression\n"));
  569.             goto abort;
  570.     }
  571.  
  572.     switch(BF.PhotometricInterpretation)
  573.     {
  574.         case BILEVEL_ZERO_IS_WHITE:
  575.             for(i=0;i<ncolors;i++)
  576.             {
  577.                 /* Set the master color table */
  578.                 cmap->red = cmap->green = cmap->blue  = (0xff/((1<<BF.BitsPerSample[0])-1))*(ncolors-i-1);
  579.  
  580.                 /* Set the color table used for remapping */
  581.                 cregs[i*3+0] = cregs[i*3+1] = cregs[i*3+2] = cmap->blue<<24;
  582.                 cmap++;
  583.             }
  584.             break;
  585.         case BILEVEL_ZERO_IS_BLACK:
  586.             for(i=0;i<ncolors;i++)
  587.             {
  588.                 /* Set the master color table */
  589.                 cmap->red   = cmap->green = cmap->blue  = (0xff/((1<<BF.BitsPerSample[0])-1))*i;
  590.  
  591.                 /* Set the color table used for remapping */
  592.                 cregs[i*3+0] = cregs[i*3+1] = cregs[i*3+2] = cmap->blue<<24;
  593.                 cmap++;
  594.             }
  595.             break;
  596.         case TRUE_COLOR_RGB:
  597.             for(i=0;i<ncolors;i++)
  598.             {
  599.                 /* Set the master color table */
  600.                 cmap->red   = i & 0xe0;
  601.                 cmap->green = (i<<3) & 0xe0;
  602.                 cmap->blue  = i<<6;
  603.  
  604.                 /* Set the color table used for remapping */
  605.                 cregs[i*3+0] = cmap->red   << 24;
  606.                 cregs[i*3+1] = cmap->green << 24;
  607.                 cregs[i*3+2] = cmap->blue  << 24;
  608.                 cmap++;
  609.             }
  610.  
  611.                 /* allocate buffer for Floyd-Steinberg dithering */
  612.             ErrRed=AllocPooled(pool,BF.ImageWidth+1);
  613.             ErrGreen=AllocPooled(pool,BF.ImageWidth+1);
  614.             ErrBlue=AllocPooled(pool,BF.ImageWidth+1);
  615.             break;
  616.         case COLOR_MAPPED_RGB:
  617.             DB (KPrintF ("Color Mapped depth=%ld\n",depth));
  618.             for(i=0;i<ncolors;i++)
  619.             {
  620.                 /* Set the master color table */
  621.                 cmap->red   = BF.ColorMap[i+0*ncolors];
  622.                 cmap->green = BF.ColorMap[i+1*ncolors];
  623.                 cmap->blue  = BF.ColorMap[i+2*ncolors];
  624.                 cmap++;
  625.  
  626.                 /* Set the color table used for remapping */
  627.                 cregs[i*3+0] = BF.ColorMap[i+0*ncolors] << 16;
  628.                 cregs[i*3+1] = BF.ColorMap[i+1*ncolors] << 16;
  629.                 cregs[i*3+2] = BF.ColorMap[i+2*ncolors] << 16;
  630.             }
  631.             break;
  632.         default:
  633.             DB (KPrintF ("Unsupported Photometric Interpretation\n"));
  634.             return FALSE;
  635.     }
  636.  
  637.  
  638.     DB (KPrintF ("getattrs\n"));
  639.     bmhd->bmh_Depth=depth;
  640.     
  641.             /* Initialize the temporary bitmap */
  642.  
  643.     poolchip=CreatePool(MEMF_CLEAR|MEMF_CHIP,8192,8192);
  644.     if(!poolchip) return FALSE;
  645.  
  646.     InitBitMap(&tbm, 8, (BF.ImageWidth +31)&~0x1f, BF.RowsPerStrip);
  647.     if(!(tbm.Planes[0]=AllocPooled(poolchip,tbm.BytesPerRow*tbm.Rows*8)))
  648.         {
  649.             DB (KPrintF ("Unable to allocate temporary bitmap\n"));
  650.             goto abort;
  651.         }
  652.     for(i=1;i<8;i++)
  653.         tbm.Planes[i]=tbm.Planes[i-1]+tbm.BytesPerRow*tbm.Rows;
  654.  
  655.  
  656.             /* allocate bitmap */
  657.  
  658.     if (bm = AllocBitMap (BF.ImageWidth, BF.ImageLength, depth, BMF_CLEAR, NULL))
  659.     {
  660.         InitRastPort (&rp);
  661.         rp.BitMap = bm;
  662.         DB (KPrintF ("Allocated bitmap\n"));
  663.     }
  664.     else
  665.     {
  666.         DB (KPrintF ("Unable to allocate bitmap\n"));
  667.         goto abort;
  668.     }
  669.  
  670.  
  671.     buffer=AllocPooled(pool,BF.RowsPerStrip*tbm.BytesPerRow*8*BF.SamplesPerPixel);
  672.     if(!buffer)
  673.     {
  674.         DB (KPrintF ("Unable to allocate buffer %ld\n",BF.RowsPerStrip*tbm.BytesPerRow*8*BF.SamplesPerPixel));
  675.         goto abort;
  676.     }
  677.  
  678.     DB (KPrintF ("Allocated buffer\n"));
  679.  
  680.     m=0;
  681.     for(i=0;i<(BF.ImageLength + BF.RowsPerStrip - 1) / BF.RowsPerStrip;i++)
  682.     {
  683.         switch(BF.Compression)
  684.         {
  685.  
  686.             case NO_COMPRESSION:
  687.                 Seek(fh,BF.StripOffsets[i],OFFSET_BEGINNING);
  688.                 if(Read(fh,buffer,BF.StripByteCounts[i])!=BF.StripByteCounts[i]) 
  689.                 {
  690.                     DB (KPrintF ("Unable to read strip %ld\n",i));        
  691.                     goto abort;
  692.                 }
  693.                 break;
  694.             case LZW:
  695.                 
  696.                 buffer3=AllocPooled(pool,BF.StripByteCounts[i]);
  697.                 if(!buffer3)
  698.                 {
  699.                     DB (KPrintF ("Unable to allocate buffer %ld\n",(long)BF.StripByteCounts[i]));
  700.                     goto abort;
  701.                 }
  702.                 Seek(fh,BF.StripOffsets[i],OFFSET_BEGINNING);
  703.                 if(Read(fh,buffer3,BF.StripByteCounts[i])!=BF.StripByteCounts[i]) 
  704.                 {
  705.                     DB (KPrintF ("Unable to read strip %ld\n",i));        
  706.                     goto abort;
  707.                 }
  708.                 j=UnPackLZW(buffer3,buffer,BF.StripByteCounts[i],cb);
  709.                 DB (KPrintF ("Uncompressed %ld bytes\n",j));        
  710.                 FreePooled(pool,buffer3,BF.StripByteCounts[i]);
  711.                 break;
  712.             default:
  713.                 DB (KPrintF ("Unsupported Compression\n"));
  714.                 goto abort;
  715.         }
  716.  
  717.         l=0;
  718.         switch(BF.PhotometricInterpretation)
  719.         {
  720.             case BILEVEL_ZERO_IS_BLACK:
  721.             case BILEVEL_ZERO_IS_WHITE:
  722.             case COLOR_MAPPED_RGB:
  723.             if(BF.BitsPerSample[0]==8)
  724.             {
  725.                 DB (KPrintF ("strip %ld\r",i));
  726.                 Chunky2Planar(tbm.BytesPerRow*8*BF.RowsPerStrip,buffer,tbm.Planes[0]);
  727.                 DB (KPrintF ("c2p %ld\n",tbm.BytesPerRow*8*BF.RowsPerStrip));
  728. //                    WritePixelLine8(&rp,0,k+i*BF.RowsPerStrip,BF.ImageWidth,buffer2,&trp);
  729.                 if(BF.ImageWidth&0xf) /* image width is not a multiple of 16 */
  730.                     for(k=0;k<BF.RowsPerStrip&& k+i*BF.RowsPerStrip<BF.ImageLength;k++)    
  731.                         BltBitMap(&tbm,k*BF.ImageWidth,0,bm,0,k+i*BF.RowsPerStrip,BF.ImageWidth,1,0xc0,0xff,NULL);
  732.                 else
  733.                     BltBitMap(&tbm,0,0,bm,0,i*BF.RowsPerStrip,BF.ImageWidth,BF.RowsPerStrip,0xc0,0xff,NULL);
  734.             }
  735.             if(BF.BitsPerSample[0]==1)
  736.                 for(k=0;k<BF.RowsPerStrip && k+i*BF.RowsPerStrip<BF.ImageLength;k++)
  737.                 {        
  738.                     DB (KPrintF ("line %ld\r",k+i*BF.RowsPerStrip));
  739.                     memcpy(bm->Planes[0]+m,buffer+l,(BF.ImageWidth+7)/8);
  740.                     m+=bm->BytesPerRow;
  741.                     l+=(BF.ImageWidth+7)/8;
  742.                 }
  743.                 break;
  744.             case TRUE_COLOR_RGB:
  745.                 {
  746.                  UBYTE r,g,b;
  747.                  int er,eg,eb,erred,ergreen,erblue,red,green,blue;
  748.                     
  749.                     ErrRed[0]=ErrGreen[0]=ErrBlue[0]=ErrRed[1]=ErrGreen[1]=ErrBlue[1]=0;
  750.                     if(BF.PlanarConfiguration==CHUNKY)
  751.                     {
  752.                         for(k=0;k<BF.RowsPerStrip && k+i*BF.RowsPerStrip<BF.ImageLength;k++)
  753.                         {        
  754.                             erred=ErrRed[0];
  755.                             ergreen=ErrGreen[0];
  756.                             erblue=ErrBlue[0];
  757.  
  758.                             DB (KPrintF ("line %ld\r",k+i*BF.RowsPerStrip));
  759.                             r=buffer[l++];
  760.                             g=buffer[l++];
  761.                             b=buffer[l++];
  762.                             buffer[k*BF.ImageWidth]= ( (((r+erred)/32)<<5) | (((g+ergreen)/32)<<2) | ((b+erblue)/64) );
  763.                             er=r & 0x1f;
  764.                             eg=g & 0x1f;
  765.                             eb=b & 0x3f;
  766.  
  767.                             erred=ErrRed[1];
  768.                             ErrRed[0]=(er*5)>>4;
  769.                             ErrRed[1]=er>>4;
  770.                             erred+=(er*7)>>4;
  771.  
  772.                             ergreen=ErrGreen[1];
  773.                             ErrGreen[0]=(eg*5)>>4;
  774.                             ErrGreen[1]=eg>>4;
  775.                             ergreen+=(eg*7)>>4;
  776.  
  777.                             erblue=ErrBlue[1];
  778.                             ErrBlue[0]=(eb*5)>>4;
  779.                             ErrBlue[1]=eb>>4;
  780.                             erblue+=(eb*7)>>4;
  781.  
  782.                             for(j=1;j<BF.ImageWidth;j++)
  783.                             {
  784.  
  785.                                 if(BF.Predictor==HORIZONTAL_DIFFERENCING)
  786.                                 {
  787.                                     red  =((buffer[l]+r)&0xff)+erred;
  788.                                     if(red>255) red=255;
  789.                                     r+=buffer[l++];
  790.                                     green=((buffer[l]+g)&0xff)+ergreen;
  791.                                     if(green>255) green=255;
  792.                                     g+=buffer[l++];
  793.                                     blue=((buffer[l]+b)&0xff)+erblue;
  794.                                     if(blue>255) blue=255;
  795.                                     b+=buffer[l++];
  796.                                 }
  797.                                 else
  798.                                 {
  799.                                     red =buffer[l]+erred;
  800.                                     if(red>255) red=255;
  801.                                     r=buffer[l++];
  802.                                     green=buffer[l]+ergreen;
  803.                                     if(green>255) green=255;
  804.                                     g=buffer[l++];
  805.                                     blue=buffer[l]+erblue;
  806.                                     if(blue>255) blue=255;
  807.                                     b=buffer[l++];
  808.                                 }
  809.     
  810.                                 buffer[k*BF.ImageWidth+j]= ( red & 0xe0) |    ((green & 0xe0)>>3) | ((blue &0xc0)>>6);
  811.                                 er=red & 0x1f;
  812.                                 eg=green & 0x1f;
  813.                                 eb=blue & 0x3f;
  814.     
  815.                                 erred=ErrRed[j+1];
  816.                                 ErrRed[j-1]+=(er*3)>>4;
  817.                                 ErrRed[j]+=(er*5)>>4;
  818.                                 ErrRed[j+1]=er>>4;
  819.                                 erred+=(er*7)>>4;
  820.  
  821.                                 ergreen=ErrGreen[j+1];
  822.                                 ErrGreen[j-1]+=(eg*3)>>4;
  823.                                 ErrGreen[j]+=(eg*5)>>4;
  824.                                 ErrGreen[j+1]=eg>>4;
  825.                                 ergreen+=(eg*7)>>4;
  826.  
  827.                                 erblue=ErrBlue[j+1];
  828.                                 ErrBlue[j-1]+=(eb*3)>>4;
  829.                                 ErrBlue[j]+=(eb*5)>>4;
  830.                                 ErrBlue[j+1]=eb>>4;
  831.                                 erblue+=(eb*7)>>4;
  832.                             }
  833. //                        WritePixelLine8(&rp,0,k+i*BF.RowsPerStrip,(BF.ImageWidth+15)&~7,buffer2,&trp);
  834.                         }
  835.                         Chunky2Planar(tbm.BytesPerRow*8*BF.RowsPerStrip,buffer,tbm.Planes[0]);
  836. //                        if(BF.ImageWidth&0x1f) /* image width is not a multiple of 32 */
  837.                             for(k=0;k<BF.RowsPerStrip&& k+i*BF.RowsPerStrip<BF.ImageLength;k++)    
  838.                                 BltBitMap(&tbm,(k*BF.ImageWidth)%(tbm.BytesPerRow*8),(k*BF.ImageWidth)/(tbm.BytesPerRow*8),bm,0,k+i*BF.RowsPerStrip,BF.ImageWidth,1,0xc0,0xff,NULL);
  839. //                        else
  840. //                            BltBitMap(&tbm,0,0,bm,0,i*BF.RowsPerStrip,BF.ImageWidth,BF.RowsPerStrip,0xc0,0xff,NULL);
  841.                     }
  842.                     if(BF.PlanarConfiguration==PLANAR) /* This is not implemented yet, since I couldn't find
  843.                                                           an image to test it */
  844.                     for(k=0;k<BF.RowsPerStrip && k+i*BF.RowsPerStrip<BF.ImageLength;k++)
  845.                     {        
  846.                         DB (KPrintF ("line %ld\r",k+i*BF.RowsPerStrip));
  847. //                        memcpy(buffer2,buffer+l,BF.ImageWidth+16);
  848. //                        WritePixelLine8(&rp,0,k+i*BF.RowsPerStrip,BF.ImageWidth,buffer2,&trp);
  849.                         l+=BF.ImageWidth;
  850.                     }
  851.                 }
  852.                 break;
  853.             default: 
  854.                 DB (KPrintF ("Unsupported PhotometricInterpretation\n"));
  855.                 goto abort;
  856.         }    
  857.     }
  858.  
  859.     setdtattrs (cb, o,
  860.             DTA_NominalHoriz,    BF.ImageWidth,
  861.             DTA_NominalVert,    BF.ImageLength,
  862.             PDTA_BitMap,        bm,
  863.             PDTA_ModeID,        modeid,
  864.         TAG_DONE);
  865.  
  866.     DeletePool(poolchip);
  867.     DB (KPrintF ("converted\n"));
  868.     return TRUE;
  869.  
  870. abort:
  871.     DeletePool(poolchip);
  872.     FreeBitMap (bm);
  873.     SetIoErr (ERROR_NO_FREE_STORE);
  874.     return FALSE;
  875.  
  876. }/*************************** convert ************************/